package com.example.test.shiro.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;


import java.util.Date;

/**
 * @author ZHUO
 * @Date 2018/10/18
 */
public class JWTUtils {


  private static String CLAIM_NAME = "userName";

  private static String CLAIM_ID = "userId";

  private static String ROLE_ID = "roleId";

  // 过期时间120分钟
  private static final long EXPIRE_TIME = 120*60*1000;

  public static String createToken(String username, String password) {
    Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
    //加密处理 password为秘钥
    Algorithm algorithm = Algorithm.HMAC256(password);
      return JWT.create()
        .withClaim(CLAIM_NAME, username)
        .withExpiresAt(date)
        .sign(algorithm);
  }

  /**
   * 生成token
   * @param userId 用户ID
   * @param secret 秘钥
   * @return
   */
  public static String createToken(Integer userId, String secret){
    Date date = new Date((System.currentTimeMillis() + EXPIRE_TIME));
    Algorithm algorithm = Algorithm.HMAC256(secret);

    return JWT.create()
            .withClaim(CLAIM_ID, userId)
            .withExpiresAt(date)//过期时间
            .sign(algorithm);//密钥
  }

  /**
   * 解析token获取用户ID
   * @param token 令牌
   * @return
   */
  public static Integer getUserId(String token){
    if(token != null){
      DecodedJWT jwt = JWT.decode(token);
      return jwt.getClaim(CLAIM_ID).asInt();
    }
    return null;
  }

  /**
   * 验证token是否已经过期合法
   * @param userId
   * @param secret
   * @return
   */
  public static boolean verify(Integer userId, String secret, String token){
    Algorithm algorithm = Algorithm.HMAC256(secret);
    JWTVerifier jwtVerifier = JWT.require(algorithm)
            .withClaim(CLAIM_ID, userId)
            .build();
    try {
      jwtVerifier.verify(token);
    }catch (JWTVerificationException e){
      return false;
    }
    return true;
  }


}
